package gui

import (
	"fmt"
	"strconv"
	"strings"
	"time"

	"github.com/gdamore/tcell/v2"
	"github.com/rivo/tview"

	v1 "baikai/ptkGUI/models"
)

// Gui have all panels
type Gui struct {
	app        *tview.Application
	pages      *tview.Pages
	rightFlex  *tview.Flex
	treeView   *tview.TreeView
	dbTreeNode *tview.TreeNode
	cmTreeNode *tview.TreeNode

	// conf *v1.Config

	dbServers []*v1.DBServer
	cmServers []*v1.CMServer
}

func New() *Gui {
	rightFlex := tview.NewFlex()
	rightFlex.SetBorder(true).SetBorderColor(tcell.ColorGreenYellow)
	treeView := tview.NewTreeView()
	treeView.SetBorder(true).SetBorderColor(tcell.ColorGreenYellow)
	pages := tview.NewPages()
	pages.SetBorder(true).SetBorderColor(tcell.ColorGreenYellow)
	return &Gui{
		app:       tview.NewApplication(),
		pages:     pages,
		rightFlex: rightFlex,
		treeView:  treeView,
		// conf:&v1.Config{Global: new(v1.Global),DBServers: []*v1.DBServer{},CMServers:[]*v1.CMServer{}},
		dbServers: []*v1.DBServer{},
		cmServers: []*v1.CMServer{},
	}
}

func (g *Gui) Start() error {
	topLeftForm := NewPtkForm("配置信息")
	topLeftForm.AddButton("Quit", func() {
		g.app.Stop()
	})
	topLeftForm.AddButton("Save", func() {

	})

	g.pages.AddPage("main", g.rightFlex, true, true)
	// 左侧 Tree
	root := tview.NewTreeNode(".").SetSelectedFunc(func() {
		g.rightFlex.SetTitle("")
		g.rightFlex.Clear()
	})

	globalInfo := &v1.Global{}

	global := tview.NewTreeNode("全局配置").SetSelectedFunc(func() {
		g.createGlobalPage(globalInfo)
		g.app.SetFocus(g.pages.SwitchToPage("global"))
	})
	// db page
	dbServers := tview.NewTreeNode("DB列表")
	g.dbTreeNode = dbServers

	dbTreeNodeSelectFunc := func() {
		dbInfo := &v1.DBServer{}
		dbFlex := g.createDBFlex(dbInfo)

		pageID := fmt.Sprintf("db:%s", dbInfo.Host)
		g.pages.AddPage(pageID, dbFlex, true, true)
		g.app.SetFocus(g.pages.SwitchToPage(pageID))
	}

	dbServers.SetSelectedFunc(dbTreeNodeSelectFunc)

	// cm page
	cmServers := tview.NewTreeNode("CM列表")
	g.cmTreeNode = cmServers

	cmServers.SetSelectedFunc(func() {
		g.updateCMServers(globalInfo)
	})

	root.AddChild(global).AddChild(dbServers).AddChild(cmServers)
	g.treeView.SetRoot(root).SetBorder(true).SetBorderColor(tcell.ColorGreenYellow)

	flex := tview.NewFlex().
		AddItem(tview.NewFlex().SetDirection(tview.FlexRow).
			AddItem(topLeftForm, 0, 1, false).
			AddItem(g.treeView, 0, 4, false), 0, 1, false).
		AddItem(g.pages, 0, 1, false)

	if err := g.app.SetRoot(flex, true).SetFocus(flex).EnableMouse(true).Run(); err != nil {
		return err
	}
	return nil
}

func (g *Gui) createGlobalPage(globalInfo *v1.Global) {
	if g.pages.HasPage("global") {
		g.app.SetFocus(g.pages.SwitchToPage("global"))
		return
	}

	globalFlex := tview.NewFlex().SetDirection(tview.FlexRow)

	globalForm, dynamicFields := createGlobal(globalInfo)
	hbaFrom := createHBAForm(globalInfo)
	gsInitParamsFlex, initParams := g.createInitParamsFlex()
	initOps := []string{}
	for _, value := range initParams {
		initOps = append(initOps, value[0])
	}
	globalInfo.GsInitdbOpts = initOps
	envFlex, envParams := g.createEnvParamsFlex()
	for _, envParam := range envParams {
		globalInfo.EnvMap[envParam[0]] = envParam[1]
	}
	cmFrom, cmOption := createCMForm()
	globalInfo.CMOption = cmOption

	globalFlex.AddItem(globalForm, 0, 9, true)
	globalFlex.AddItem(dynamicFields, 0, 7, true)
	globalFlex.AddItem(hbaFrom, 0, 4, true)
	globalFlex.AddItem(gsInitParamsFlex, 0, 8, true)
	globalFlex.AddItem(envFlex, 0, 8, true)
	globalFlex.AddItem(cmFrom, 0, 7, true)

	g.pages.AddPage("global", globalFlex, true, true)
}

func (g *Gui) updateCMServers(globalInfo *v1.Global) {
	cmServers := g.cmTreeNode
	if len(g.cmServers) != 0 {
		return
	}
	cmServers.ClearChildren()

	// 确保在全局配置中启用了CM，并且CM目录不为空
	if globalInfo != nil && globalInfo.CMOption != nil && globalInfo.CMOption.Dir != "" {
		if len(g.dbServers) != 0 {
			for _, server := range g.dbServers {
				g.cmServers = append(g.cmServers, &v1.CMServer{Host: server.Host})
			}
		}
		for _, cm := range g.cmServers {
			cmInfo := cm
			selectedFunc := func() {
				cmFlex := g.createCMFlex(cmInfo, cmInfo.Host)
				cmPage := fmt.Sprintf("cm:%s", cmInfo.Host)
				g.pages.AddPage(cmPage, cmFlex, true, true)
				g.app.SetFocus(g.pages.SwitchToPage(cmPage))
			}
			cmPage := fmt.Sprintf("cm:%s", cmInfo.Host)
			cmNode := tview.NewTreeNode(cmPage).SetSelectedFunc(selectedFunc)
			cmServers.AddChild(cmNode)

			// cm := cmInfo
			// selectedFunc := func() {
			// 	newCMInfo := &v1.CMServer{}
			// 	cmFlex := g.createCMFlex(newCMInfo, cm.Host)
			// 	cmPage := fmt.Sprintf("cm:%s", cm.Host)
			// 	g.pages.AddPage(cmPage, cmFlex, true, true)
			// 	g.app.SetFocus(g.pages.SwitchToPage(cmPage))
			// }
			// cmNode := tview.NewTreeNode(cm.Host).SetSelectedFunc(selectedFunc)
			// cmServers.AddChild(cmNode)
		}
	} else {
		// 如果没有全局配置或CM目录为空，确保不添加空子节点
		if len(cmServers.GetChildren()) == 0 {
			cmInfo := &v1.CMServer{}
			cmFlex := g.createCMFlex(cmInfo, "")
			cmPage := fmt.Sprintf("cm:%s", cmInfo.Host)
			g.pages.AddPage(cmPage, cmFlex, true, true)
		}
	}
}

func (g *Gui) createCMForm(cmInfo *v1.CMServer, ip string) *tview.Form {
	form := tview.NewForm()
	form.AddInputField("cmServerIP", ip, 20, nil, func(text string) {
		cmInfo.Host = text
	})
	form.AddInputField("HAIPS", "", 20, nil, func(text string) {
		cmInfo.HAIPs = []string{text}
	})
	return form
}

func (g *Gui) createCMFlex(cmInfo *v1.CMServer, ip string) *tview.Flex {
	cmFlex := tview.NewFlex().SetDirection(tview.FlexRow)

	cmInfoForm := g.createCMForm(cmInfo, ip)

	sshOption := &v1.SSHOption{}
	sshForm := createSSHForm(sshOption)
	cmInfo.SSHOption = sshOption

	buttonForm := tview.NewForm()
	buttonForm.AddButton("保存", func() {
		// 保存输入、
		cmPage := fmt.Sprintf("cm:%s", cmInfo.Host)
		g.pages.AddPage(cmPage, cmFlex, true, true)
		g.cmTreeNode.AddChild(tview.NewTreeNode(cmPage).SetSelectedFunc(
			func() {
				g.pages.SwitchToPage(cmPage)
			}))
		g.cmServers = append(g.cmServers, cmInfo)
	})
	buttonForm.AddButton("新增", func() {
		// 新增一个新页面
		newCMInfo := &v1.CMServer{}
		newCMFlex := g.createCMFlex(newCMInfo, "")
		g.pages.AddPage(newCMInfo.Host, newCMFlex, true, true)
		g.app.SetFocus(g.pages.SwitchToPage(newCMInfo.Host))

	})
	buttonForm.AddButton("删除", func() {
		// 删除对应ip子项
		cmPage := fmt.Sprintf("cm:%s", cmInfo.Host)
		g.RemoveChildByText(g.cmTreeNode, cmPage)
		// 删除page
		g.pages.RemovePage(cmPage)
		g.RemoveCMByIP(cmInfo.Host)
		g.app.SetFocus(g.pages)
	})

	cmFlex.AddItem(cmInfoForm, 0, 4, true)
	cmFlex.AddItem(sshForm, 0, 11, true)
	cmFlex.AddItem(buttonForm, 0, 2, false)
	return cmFlex
}

func (g *Gui) createDBFlex(dbInfo *v1.DBServer) *tview.Flex {
	// dbFlex
	dbFlex := tview.NewFlex().SetDirection(tview.FlexRow)

	// db base
	dbBaseInfoForm := createDBBaseInfoForm(dbInfo)
	// create ssh form
	sshOption := &v1.SSHOption{}
	sshForm := createSSHForm(sshOption)
	dbInfo.SSHOption = sshOption
	// create Haips
	haIPsForm := createHaIPsForm(dbInfo)
	// create az
	azInfoFrom := createAzForm(dbInfo)
	// create db-conf
	dbConfForm, dbConf := g.createDBConfFlex()
	for _, envParam := range dbConf {
		dbInfo.DBConf[envParam[0]] = envParam[1]
	}
	// create env form
	envForm, envParams := g.createEnvParamsFlex()
	for _, envParam := range envParams {
		dbInfo.EnvMap[envParam[0]] = envParam[1]
	}

	// button
	buttonForm := tview.NewForm()
	buttonForm.AddButton("保存", func() {
		ip := dbInfo.Host
		// 创建唯一的页面ID
		pageID := fmt.Sprintf("db:%s", ip)

		dbNode := tview.NewTreeNode(ip).SetSelectedFunc(func() {
			g.pages.SwitchToPage(pageID)
			g.app.SetFocus(g.pages.SwitchToPage(pageID))
		})
		g.dbTreeNode.AddChild(dbNode)
		g.pages.AddPage(pageID, dbFlex, true, true)
		g.dbServers = append(g.dbServers, dbInfo)

	})
	buttonForm.AddButton("新增", func() {
		newDBInfo := &v1.DBServer{}
		newDBFlex := g.createDBFlex(newDBInfo)
		pageID := fmt.Sprintf("db:%s", newDBInfo.Host)
		g.pages.AddPage(pageID, newDBFlex, true, true)
		g.app.SetFocus(g.pages.SwitchToPage(pageID))
	})
	buttonForm.AddButton("删除", func() {
		// 删除对应ip子项
		g.RemoveChildByText(g.dbTreeNode, dbInfo.Host)
		// 删除page
		g.pages.RemovePage(fmt.Sprintf("db:%s", dbInfo.Host))
		g.RemoveDBByIP(dbInfo.Host)
		g.app.SetFocus(g.pages.SwitchToPage(fmt.Sprintf("db:%s", dbInfo.Host)))

	})

	dbFlex.AddItem(dbBaseInfoForm, 0, 4, true)
	dbFlex.AddItem(sshForm, 0, 11, true)
	dbFlex.AddItem(haIPsForm, 0, 3, true)
	dbFlex.AddItem(azInfoFrom, 0, 4, true)
	dbFlex.AddItem(dbConfForm, 0, 5, true)
	dbFlex.AddItem(envForm, 0, 5, true)
	dbFlex.AddItem(buttonForm, 0, 2, false)

	return dbFlex
}

func (g *Gui) RemoveDBByIP(ip string) {
	for i, dbServer := range g.dbServers {
		if dbServer.Host == ip {
			g.dbServers = append(g.dbServers[:i], g.dbServers[i+1:]...)
			return
		}
	}
}
func (g *Gui) RemoveCMByIP(ip string) {
	for i, cmServer := range g.cmServers {
		if cmServer.Host == ip {
			g.cmServers = append(g.cmServers[:i], g.cmServers[i+1:]...)
			return
		}
	}
}

func createAzForm(dbInfo *v1.DBServer) *tview.Form {
	azInfoForm := tview.NewForm()

	azInfoChecked := func(checked bool) {
		if checked {
			azInfoForm.AddInputField("可用区", "Az1", 20, nil, func(text string) {
				if text != "" {
					dbInfo.AzName = text
				}
			})
			azInfoForm.AddInputField("优先级", "1", 20, nil, func(text string) {
				if text != "" {
					i, err := strconv.Atoi(text)
					if err != nil {
						return
					}
					dbInfo.AzPriority = i
				}
			})
		} else {
			azInfoForm.RemoveFormItem(azInfoForm.GetFormItemIndex("可用区"))
			azInfoForm.RemoveFormItem(azInfoForm.GetFormItemIndex("优先级"))
			dbInfo.AzName = ""
			dbInfo.AzPriority = 0
		}
	}

	azInfoForm.AddCheckbox("配置可用区和优先级", false, azInfoChecked)
	return azInfoForm
}

func createHaIPsForm(dbInfo *v1.DBServer) *tview.Form {
	haIPs := tview.NewForm()

	haIPsChecked := func(checked bool) {
		if checked {
			haIPs.AddInputField("数据库冗余 IP", "", 20, nil, func(text string) {
				if text != "" {
					dbInfo.HAIPs = []string{text}
				}
			})
		} else {
			haIPs.RemoveFormItem(haIPs.GetFormItemIndex("数据库冗余 IP"))
			dbInfo.HAIPs = []string{}
		}
	}

	haIPs.AddCheckbox("配置双网段", false, haIPsChecked)
	return haIPs
}

func createSSHForm(sshOption *v1.SSHOption) *tview.Form {
	sshForm := tview.NewForm()

	sshFormInputs := func(f *tview.Form, sshInfo *v1.SSHOption) {
		f.AddInputField("目标数据器 IP", "", 20, nil, func(text string) {
			if text != "" {
				sshInfo.Host = text
			}
		})
		f.AddInputField("SSH 服务器端口", "", 20, nil, func(text string) {
			if text != "" {
				port, err := strconv.Atoi(text)
				if err != nil {
					return
				}
				sshInfo.Port = port
			}
		})
		f.AddInputField("登录用户", "", 20, nil, func(text string) {
			if text != "" {
				sshInfo.User = text
			}
		})
		f.AddInputField("登录用户密码", "", 20, nil, func(text string) {
			if text != "" {
				// 需要加密
				sshInfo.Password = text
			}
		})
		f.AddInputField("登录密钥文件路径", "", 20, nil, func(text string) {
			if text != "" {
				sshInfo.KeyFile = text
			}
		})
		f.AddInputField("登录超时时间", "", 20, nil, func(text string) {
			if text != "" {
				// 单位 m
				t, err := strconv.Atoi(text)
				if err != nil {
					return
				}
				sshInfo.ConnTimeout = time.Duration(t)
			}
		})
		f.AddInputField("执行单条命令超时时间", "", 20, nil, func(text string) {
			if text != "" {
				t, err := strconv.Atoi(text)
				if err != nil {
					return
				}
				sshInfo.ExecTimeout = time.Duration(t)
			}
		})
	}
	sshCheckedFunc := func(checked bool) {
		if checked {
			sshFormInputs(sshForm, sshOption)
			sshForm.AddCheckbox("Proxy", false, func(checked bool) {
				if checked {
					proxySsh := &v1.SSHOption{}
					sshFormInputs(sshForm, proxySsh)
					sshOption.Proxy = proxySsh
				} else {
					for {
						proxyIndex := sshForm.GetFormItemIndex("Proxy")
						if proxyIndex != -1 && proxyIndex == sshForm.GetFormItemCount()-1 {
							break
						}
						sshForm.RemoveFormItem(proxyIndex + 1)
					}
					sshOption.Proxy = nil
				}
			})
		} else {
			for i := sshForm.GetFormItemCount() - 1; i >= 0; i-- {
				if !strings.HasPrefix(sshForm.GetFormItem(i).GetLabel(), "配置SSH连接") {
					sshForm.RemoveFormItem(i)
				}
			}
			sshOption = nil
		}
	}
	sshForm.AddCheckbox("配置SSH连接信息", false, sshCheckedFunc)
	return sshForm
}

func createDBBaseInfoForm(dbInfo *v1.DBServer) *tview.Form {
	dbBaseForm := tview.NewForm()
	dbBaseForm.AddInputField("数据库IP", "", 20, nil, func(text string) {
		dbInfo.Host = text
	})
	dbBaseForm.AddDropDown("角色", []string{"主库", "备库", "级联备库"}, 0, func(option string, optionIndex int) {
		switch option {
		case "主库":
			dbInfo.Role = "primary"
		case "备库":
			dbInfo.Role = "standby"
		case "级联备库":
			dbInfo.Role = "cascade_standby"
			upStram := tview.NewInputField().SetLabel("上游库").SetChangedFunc(func(text string) {
				dbInfo.UpstreamHost = text
			})
			InsertFormItem(dbBaseForm, dbBaseForm.GetFormItemIndex("角色")+1, upStram)
		}
		dbInfo.Role = option
	})
	dbBaseForm.AddInputField("系统用户", "", 20, nil, func(text string) {
		if text != "" {
			dbInfo.User = text
		}
	})
	dbBaseForm.AddInputField("系统用户组", "", 20, nil, func(text string) {
		if text != "" {
			dbInfo.Group = text
		}
	})
	dbBaseForm.AddInputField("系统用户密码", "", 20, nil, func(text string) {
		if text != "" {
			// 需要加密
			dbInfo.UserPassword = text
		}
	})
	dbBaseForm.AddInputField("数据库端口", "", 20, nil, func(text string) {
		if text != "" {
			port, err := strconv.Atoi(text)
			if err != nil {
				return
			}
			dbInfo.DBPort = port
		}
	})
	dbBaseForm.AddInputField("数据库Xlog日志目录", "", 20, nil, func(text string) {
		if text != "" {
			dbInfo.XLogDir = text
		}
	})
	return dbBaseForm
}

func createGlobal(g *v1.Global) (*tview.Form, *tview.Form) {
	globalForm := tview.NewForm()
	dynamicFields := tview.NewForm()
	globalForm.AddInputField("集群名", "", 20, nil, func(text string) {
		g.ClusterName = text
	})
	globalForm.AddInputField("系统用户名", "", 20, nil, func(text string) {
		g.User = text
	})
	globalForm.AddInputField("用户组", "", 20, nil, func(text string) {
		g.Group = text
	})
	globalForm.AddInputField("数据库端口", "", 20, nil, func(text string) {
		port, err := strconv.Atoi(text)
		if err != nil {
			//
		}
		g.DBPort = port
	})
	globalForm.AddInputField("用户密码", "", 20, nil, nil)
	globalForm.AddInputField("数据库密码", "", 20, nil, nil)
	globalForm.AddInputField("安装目录", "", 20, nil, func(text string) {
		updateDependentFields(dynamicFields, text)
		g.BaseDir = text

	})
	return globalForm, dynamicFields
}

func updateDependentFields(form *tview.Form, baseDir string) {
	form.Clear(false)

	if strings.TrimSpace(baseDir) != "" {
		form.AddInputField("appDir", baseDir+"/app", 30, nil, nil)
		form.AddInputField("dataDir", baseDir+"/data", 30, nil, nil)
		form.AddInputField("logDir", baseDir+"/log", 30, nil, nil)
		form.AddInputField("toolDir", baseDir+"/tool", 30, nil, nil)
		form.AddInputField("tmpDir", baseDir+"/tmp", 30, nil, nil)
	} else {
		form.Clear(false)
	}
}

// 创建HBA表单
func createHBAForm(g *v1.Global) *tview.Form {

	// flex := tview.NewFlex()  grid
	// flex.AddItem()
	form := tview.NewForm()
	// buttonForm := tview.NewForm().AddButton()

	form.SetBorder(false)
	hbaInputField := tview.NewInputField().
		SetLabel("访问数据库IP的地址").
		SetFieldWidth(20).SetChangedFunc(func(text string) {
		// g.ExtraHBAConf
	})
	form.AddCheckbox("配置HBA白名单", false, func(checked bool) {
		if checked {
			InsertFormItem(form, form.GetFormItemIndex("配置HBA白名单")+1, hbaInputField)
		} else {
			form.RemoveFormItem(form.GetFormItemIndex("访问数据库IP的地址"))
		}
	})
	return form
}

func InsertFormItem(form *tview.Form, index int, item tview.FormItem) {
	itemCount := form.GetFormItemCount()

	newItems := make([]tview.FormItem, 0)

	for i := 0; i < itemCount; i++ {
		if i == index {
			newItems = append(newItems, item)
		}
		newItems = append(newItems, form.GetFormItem(i))
	}

	if index >= itemCount {
		newItems = append(newItems, item)
	}

	form.Clear(false)
	for _, newItem := range newItems {
		form.AddFormItem(newItem)
	}
}

// 创建环境变量表单
func (g *Gui) createDBConfFlex() (*tview.Flex, [][]string) {
	return g.createCheckboxWithTableFlex([]string{"key", "value", "operate"}, "配置数据库参数", false)
}

// 创建环境变量表单
func (g *Gui) createEnvParamsFlex() (*tview.Flex, [][]string) {
	return g.createCheckboxWithTableFlex([]string{"key", "value", "operate"}, "配置环境变量", false)
}

// 创建初始化参数表单
func (g *Gui) createInitParamsFlex() (*tview.Flex, [][]string) {
	return g.createCheckboxWithTableFlex([]string{"params", "operate"}, "配置初始化参数", true)
}

func (g *Gui) createCheckboxWithTableFlex(tableHeader []string, checkboxLabel string, haveOneInput bool) (*tview.Flex, [][]string) {
	flex := tview.NewFlex()
	flex.SetDirection(tview.FlexRow)

	table := NewTable(tableHeader)
	table.InitHeaders()

	// 创建一个初始化参数中的新增按钮
	addButton := tview.NewButton("新增")
	addButton.SetBackgroundColor(tcell.ColorRed).SetTitleColor(tcell.ColorGreen)

	selectedFunc := func() {
		form := NewPtkForm("")
		if haveOneInput {
			form.AddInputField("初始化参数", "", 20, nil, nil)
		} else {
			form.AddInputField("key", "", 20, nil, nil)
			form.AddInputField("value", "", 20, nil, nil)
		}

		form.AddButton("Save", func() {
			row := []string{}
			if haveOneInput {
				value := form.GetFormItemByLabel("初始化参数").(*tview.InputField).GetText()
				row = append(row, value)
			} else {
				key := form.GetFormItemByLabel("key").(*tview.InputField).GetText()
				value := form.GetFormItemByLabel("value").(*tview.InputField).GetText()
				row = append(row, key)
				row = append(row, value)
			}

			table.SetRowInfo([][]string{row})
			table.Refresh()
			g.pages.RemovePage("modal")
			g.app.SetFocus(g.pages.ShowPage("main"))
		}).AddButton("Cancel", func() {
			g.pages.RemovePage("modal")
			g.app.SetFocus(g.pages.ShowPage("main"))
		})

		g.pages.AddPage("modal", NewModalForFlex(form, 40, 10), true, true)
	}

	addButton.SetSelectedFunc(selectedFunc)

	// 调整按钮大小
	buttonFlex := tview.NewFlex().
		SetDirection(tview.FlexColumn).
		AddItem(nil, 1, 1, false).
		AddItem(addButton, 8, 1, true).
		AddItem(nil, 1, 1, false)

	tableFlex := tview.NewFlex().
		SetDirection(tview.FlexRow).
		AddItem(table, 0, 1, true).
		AddItem(buttonFlex, 2, 1, false)

	// 创建一个checkbox
	checkbox := tview.NewCheckbox().SetLabel(checkboxLabel)
	checkboxFunc := func(check bool) {
		if check {
			flex.AddItem(tableFlex, 0, 1, true)
		} else {
			flex.RemoveItem(tableFlex)
		}
	}
	checkbox.SetChangedFunc(checkboxFunc)

	flex.AddItem(tview.NewForm().AddFormItem(checkbox), 0, 1, false)

	// return initParams, table.RowData
	return flex, table.RowData
}

// 创建CM安装表单
func createCMForm() (*tview.Form, *v1.CMOption) {
	form := tview.NewForm()
	cmOption := &v1.CMOption{}
	form.AddCheckbox("安装CM", false, func(checked bool) {
		if checked {

			form.AddInputField("CM 安装目录", "", 20, nil, func(text string) {
				cmOption.Dir = text
			})
			form.AddInputField("CM Server 端口", "", 20, nil, func(text string) {
				port, err := strconv.Atoi(text)
				if err != nil {
					return
				}
				cmOption.CmServerPort = port
			})
			form.AddInputField("虚拟 IP", "", 20, nil, func(text string) {
				cmOption.DBServiceVIP = text
			})
			form.AddInputField("CM Server 配置", "", 20, nil, nil)
			form.AddInputField("CM Agent 配置", "", 20, nil, nil)
		} else {
			for i := form.GetFormItemCount() - 1; i >= 0; i-- {
				if form.GetFormItem(i).GetLabel() != "安装CM" {
					form.RemoveFormItem(i)
				}
			}
		}
	})
	return form, cmOption
}

func (g *Gui) RemoveChildByText(treeNode *tview.TreeNode, key string) {
	for _, child := range treeNode.GetChildren() {
		if key == child.GetText() {
			treeNode.RemoveChild(child)
			return
		}
	}
}
